/*
 * ToString
 * 把任何类型转换成`String`，只需要实现那个类型的`ToString` trait。
 * 通过实现`fmt::Display` trait, 它会自动提供`ToString`，并且还可以
 * 用来打印类型。
 */
use std::fmt;
use std::str::FromStr;

struct Circle {
    radius: i32,
}

impl fmt::Display for Circle {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Circle of radius {}", self.radius)
    }
}

impl FromStr for Circle {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let astr = &s[1..s.len()-1];
        match astr.parse::<i32>() {
            Ok(n) => Ok(Circle {radius: n}),
            Err(_) => Err(())
        }
    }
}

fn main() {
    let circle = Circle { radius: 6 };
    println!("{}", circle.to_string());

    /*
     * 把字符串转成数字，标准手段是用`parse`函数。
     * 只要对目标类型实现了 `FromStr` trait，就可以用`parse`把字符串转换成
     * 目标类型。如果要转换到用户自定义类型，只要手动实现 `FromStr` 就行
     */
    let parsed: i32 = "5".parse().unwrap();
    println!("{}", parsed);

    let astr = "<500>";
    let xcircle: Circle = astr.parse().unwrap();
    println!("{}", xcircle);
}